#!/usr/bin/env python
# encoding: utf-8
"""
tests.py

Created by Christopher Humphries and Maxime Simon
"""

import getopt
import os
import sys

from os import path
from subprocess import call
from sys import exit


# Tests to skip
skip = ["level4diverge.vsl"]


def runLevelTest(level):
    """ Run all tests from a given level. """
    nbFail = 0
    pathname = "../tests/testlevel" +str(level)
    files = os.listdir(pathname)
    
    for test in files:
        # If extension is .vsl and is not in the skip list
        if path.splitext(test)[1] == ".vsl" and test not in skip:
            sys.stdout.write(test + "...\t")
            filename = path.join(pathname, test)
            failed = runTest(filename)
            
            if failed == 0:
                print("PASSED")
            else:
                nbFail += failed
                print("FAILED")
    
    return nbFail


def runTest(filename):
    """ Run an unary test. """
    # Compile
    test = path.splitext(path.basename(filename))[0]
    
    output = "../nachos/test/" + test + ".s"
    compilation = ["../script/run.sh", "Vsl", filename, output]
    retcode = call(compilation, stdout=open('/dev/null', 'w'))
    if retcode != 0:
        return 1
    
    os.chdir("../nachos/")
    
    # Build
    build = ["./build.sh", test]
    retcode = call(build, stdout=open('/dev/null', 'w'))
    if retcode != 0:
        os.chdir("../src/")
        return 1
    
    # Execute
    execute = ["./exec.sh", test]
    retcode = call(execute, stdout=open('/dev/null', 'w'), stdin=open('../tests/stdin', 'r'))
    if retcode != 0:
        os.chdir("../src/")
        return 1
    
    os.chdir("../src/")
    return 0


def main():
    # Check current directory
    pwd = os.getcwd()
    
    if path.basename(pwd) != "src":
        exit("Trying to run tests from an incorrect directory.")
    
    nbFail = 0
    
    # Get arguments (if any)
    try:
        opts, args = getopt.getopt(sys.argv[1:], "")
    except getopt.GetoptError, err:
        print str(err)
        sys.exit(2)
    
    if len(args) == 0:
        # Run tests for each level
        for level in [1, 2, 3, 4]:
            print("\nLevel " + str(level) + "...")
            retcode = runLevelTest(level)
            
            if retcode != 0:
                nbFail += retcode
                print(str(retcode) + " test(s) failed.")
            else:
                print("Level completed.")
    else:
        # Run tests passed as argument
        for test in args:
            # If extension is .vsl and is not in the skip list
            if path.splitext(test)[1] == ".vsl" and test not in skip:
                sys.stdout.write(path.basename(test) + "...\t")
                failed = runTest(test)
                
                if failed == 0:
                    print("PASSED")
                else:
                    nbFail += failed
                    print("FAILED")
    
    if nbFail != 0:
        exit("\n" + str(nbFail) + " test(s) failed.")
    
    print("\nAll tests completed. Congratulations!")


if __name__ == '__main__':
    main()
